package pacBioSimple;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import pacBiopackage.GetOpt;
import tools.kmer.KmerSet_binary;
import tools.kmer.kmerFunctions;

public class PacBioSequenceEntropyInbetweenSeedsMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
			GetOpt go = new GetOpt(args, "o:k:a:h:n:l:j");
			go.optErr = true;
			int ch = -1;
			
			// process options in command line arguments
			// Set default values
			boolean usagePrint = false;                 
			String filenameAlignment = "";   
			String filenameOutput="output.txt";
			String filenameKmerObject = "";
			boolean jelly=false;
			int kmer_count_limit =100000;
			int left_limit=42;
			while ((ch = go.getopt()) != GetOpt.optEOF) 
			{
			    if ((char)ch == 'h') {
			       usagePrint = true;
			   }
			    else if ((char)ch == 'a') {
			    	filenameAlignment = go.optArgGet();
			    }
			    else if((char)ch =='o')
			    {
			    	filenameOutput = go.optArgGet();
			    }
			    else if((char)ch =='k')
			    {
			    	filenameKmerObject=go.optArgGet();
			    }
			    else if((char)ch =='n')
			    {
			    	kmer_count_limit=Integer.valueOf(go.optArgGet());
			    }
			    else if((char)ch =='j')
			    {
			    	jelly=true;
			    }
			    else if((char)ch =='l')
			    {
			    	left_limit=Integer.valueOf(go.optArgGet());
			    }
			    else
			        System.exit(1);                     // undefined option
			}                                           // getopt() returns '?'
			
			if (usagePrint || filenameKmerObject.isEmpty() || filenameAlignment.isEmpty()) {
			    System.out.println("Usage: -a PacBio -k Kmer -n kmer_count_limit -l left_limit -j[ -o outputFile -h]"); //NOI18N
			    System.exit(0);
			}
			
			// @TODO check if files exist
		
			System.out.println("------------------------");
			System.out.println("Command line parameter settings:");
			System.out.println("-a " + filenameAlignment); //NOI18N
			System.out.println("-o " + filenameOutput); //NOI18N
			System.out.println("-n " + kmer_count_limit); //NOI18N
			System.out.println("-l " + left_limit); //NOI18N
			System.out.println("-k " + filenameKmerObject); //NOI18N
			System.out.println("-j " + jelly); //NOI18N
			System.out.println("------------------------");
			
			
			//first we have to read the kmersFromthe file
			KmerSet_binary ks = null;
			BufferedReader in;
			try 
			{
//				FileHandler fh = new FileHandler("log");
//				log.addHandler(fh);
				in = new BufferedReader(new FileReader(filenameKmerObject));
				String kmer;
				System.out.println("reading kmers");
				
				if(!jelly)
				{
					while(in.ready())
					{
						kmer=in.readLine();
						if(kmer.indexOf('N')==-1 && Integer.valueOf(kmer.split("\t")[0]) >=left_limit && Integer.valueOf(kmer.split("\t")[0]) <= kmer_count_limit )
						{
							if(ks !=null)
							{
								 ks.addKmer(kmerFunctions.kmerToUse(kmer.split("\t")[1]),Integer.valueOf(kmer.split("\t")[0])); //already checked for revComp....
							}
							else
							{
								ks= new KmerSet_binary(kmer.split("\t")[1].length());
								ks.addKmer(kmerFunctions.kmerToUse(kmer.split("\t")[1]),Integer.valueOf(kmer.split("\t")[0]));
							}
						}
					}
				}
				else
				{
					while(in.ready())
					{
						kmer=in.readLine();
						if(kmer.indexOf('N')==-1 && Integer.valueOf(kmer.split("\t")[1]) >=left_limit && Integer.valueOf(kmer.split("\t")[1]) <= kmer_count_limit )
						{
							if(ks !=null)
							{
								 ks.addKmer(kmerFunctions.kmerToUse(kmer.split("\t")[0]),Integer.valueOf(kmer.split("\t")[1])); //already checked for revComp....
							}
							else
							{
								ks= new KmerSet_binary(kmer.split("\t")[0].length());
								ks.addKmer(kmerFunctions.kmerToUse(kmer.split("\t")[0]),Integer.valueOf(kmer.split("\t")[1]));
							}
						}
					}
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
			BufferedReader br = null;
			try
			{
				//kmer_count_limit=170;
				br = new BufferedReader(new FileReader(filenameAlignment));
				PrintWriter containseeds = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_contain_seeds"))); 
				PrintWriter containseeds_not = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_not_contain_seeds")));
				PrintWriter pw2 =new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_single")));
				PrintWriter pw3 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_entropy_seeds")));
				
				PrintWriter pw4 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_seed_numbers")));
				PrintWriter pw5 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_seed_sequence_entropy_scale")));
				PrintWriter pw6 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_entropy_seeds_max_per_read")));
				PrintWriter pw7 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_entropy_seeds_sequence_entropy_per_read")));
				//PacBioErrorStatisticsContainer stat = new PacBioErrorStatisticsContainer();
				CodingTable table = new CodingTable();
				PacBioMaster correctionKmer = new PacBioMaster(ks, table,kmer_count_limit, null,0.0);
				//PacBioCorrectionByKmers kmerCorrection = new PacBioCorrectionByKmers(ks,stat,freq_mode,freq_table);
				System.out.println("starting correction");
				List<Character> alphabet = new ArrayList<Character>();
				
				alphabet.add('A');
				alphabet.add('C');
				alphabet.add('G');
				alphabet.add('T');
				
				Entropy<Character>entropy = new Entropy<Character>(alphabet);
				
				String alphabet2 ="AAACAGATCACCCGCTGAGCGGGTTATCTGTT";
				List<StringBuilder> alpha = new ArrayList<StringBuilder>();
				for(int i=0; i <=alphabet2.length()-2;i+=2)
				{
					String temp=  alphabet2.substring(i, i+2);
					alpha.add(new StringBuilder(temp));
				}
				
				Entropy<StringBuilder>dimer = new Entropy<StringBuilder>(alpha);
				
				while(br.ready())
				{
					//test if we are getting a copy of br or if its counting up
					PacBioReadContainer read = new PacBioReadIntoContainer().readIntoContainer(br);
					Pair<List<Double>,List<Double>> resultPair =correctionKmer.sequenceEntropy(read, dimer,entropy); 
					List<Double> result=resultPair.getFirst();
					double max=0;
					for(int i=0; i < result.size();++i)
					{
						if(result.get(i)>max)
						{
							max=result.get(i);
						}
						pw3.append(String.valueOf(result.get(i))+"\n");
					}
					List<Double> result2=resultPair.getSecond();
					double sum=0;
					for(int i=0; i < result2.size();++i)
					{
						sum+=result2.get(i);
						pw7.append(String.valueOf(result2.get(i))+" ");
					}
					pw7.append("\n");
					sum/=result2.size();
					pw5.append(sum+"\n");
					
					
					pw6.append(String.valueOf(max)+"\n");
					pw4.append(String.valueOf(result.size()));
					pw4.append("\n");
					List<Integer>seedsResult = correctionKmer.getSeeds();
					if(seedsResult.size()==0)
					{
						containseeds_not.append(read.getHeader()+"\n");
					}
					else
					{
						containseeds.append(read.getHeader()+"\n");
					}
					for(int i=0; i < seedsResult.size();++i)
					{
						pw2.append(String.valueOf(seedsResult.get(i))+" ");
					}
					pw2.append("\n");
					
				}
				containseeds.flush();
				containseeds_not.flush();
				pw2.flush();
				pw3.flush();
				pw4.flush();
				pw5.flush();
				pw6.flush();
				pw7.flush();
				
				pw2.close();
				pw3.close();
				pw4.close();
				pw5.close();
				pw6.close();
				pw7.close();
				containseeds.close();
				containseeds_not.close();
				
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}


	}

